package org.example;

import org.example.gen.LocationMapGen;
import org.example.gen.MapGen;
import org.example.gen.SurveyExcelGen;
import org.example.gen.WordGen;
import org.example.tool.ExcelTool;
import org.example.tool.ShapeTool;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;


public class Main extends JFrame implements LogInterface{
    // 定义组件
    private JLabel insuredPlotLabel;
    private JTextField insuredPlotField;
    private JButton insuredPlotBtn;

    private JLabel resultTypeLabel;
    private JCheckBox themeCheckBox, locateCheckBox, reporeCheckBox, wordCheckBox;

    private JLabel plantingRatioLabel, verificationRatioLabel;
    private JTextField plantingRatioField, verificationRatioField;

    private JLabel plotFilterLogicLabel;
    private JCheckBox fullPlotCheckBox, highestRatioCheckBox;

    private JLabel statTableLabel;
    private JTextField statTableField;
    private JButton statTableBtn;

    private JLabel outputPathLabel;
    private JTextField outputPathField;
    private JButton outputPathBtn;

    private JButton clearBtn, outputBtn;

    private JTabbedPane tabbedPane;

    private FileDirTool fileDirTool;
    private ShapeEntity shapeEntity;
    private LocationMapGen locationMapGen;
    // 新增组件：进度条和日志区域
    private JProgressBar progressBar;
    private JTextPane logArea;
    private JScrollPane logScrollPane;
    private StyledDocument doc;
    public Main() {
        // 初始化窗口
        setTitle("制图及成果报告工具");
        setSize(800, 700); // 增加高度以容纳新增组件
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 初始化组件
        initComponents();
        // 设置布局
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 添加“承保地块”相关组件
        gbc.gridx = 0;
        gbc.gridy = 0;
        add(insuredPlotLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        add(insuredPlotField, gbc);

        gbc.gridx = 3;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        add(insuredPlotBtn, gbc);

        // 添加“成果类型”相关组件
        gbc.gridx = 0;
        gbc.gridy = 1;
        add(resultTypeLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        add(themeCheckBox, gbc);

        gbc.gridx = 2;
        gbc.gridy = 1;
        add(locateCheckBox, gbc);

        gbc.gridx = 3;
        gbc.gridy = 1;
        add(reporeCheckBox, gbc);

        gbc.gridx = 4;
        gbc.gridy = 1;
        add(wordCheckBox, gbc);

        // 添加“种植占比”和“验标比例”相关组件
        gbc.gridx = 0;
        gbc.gridy = 2;
        add(plantingRatioLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 2;
        add(plantingRatioField, gbc);

        gbc.gridx = 2;
        gbc.gridy = 2;
        add(verificationRatioLabel, gbc);

        gbc.gridx = 3;
        gbc.gridy = 2;
        add(verificationRatioField, gbc);

        // 添加“地块筛选逻辑”相关组件
        gbc.gridx = 0;
        gbc.gridy = 3;
        add(plotFilterLogicLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 3;
        add(fullPlotCheckBox, gbc);

        gbc.gridx = 2;
        gbc.gridy = 3;
        add(highestRatioCheckBox, gbc);

        // 添加“统计表格”相关组件
        gbc.gridx = 0;
        gbc.gridy = 4;
        add(statTableLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 4;
        gbc.gridwidth = 2;
        add(statTableField, gbc);

        gbc.gridx = 3;
        gbc.gridy = 4;
        gbc.gridwidth = 1;
        add(statTableBtn, gbc);

        // 添加“输出路径”相关组件
        gbc.gridx = 0;
        gbc.gridy = 5;
        add(outputPathLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 5;
        gbc.gridwidth = 2;
        add(outputPathField, gbc);

        gbc.gridx = 3;
        gbc.gridy = 5;
        gbc.gridwidth = 1;
        add(outputPathBtn, gbc);

        // 添加“清除”和“输出”按钮
        gbc.gridx = 2;
        gbc.gridy = 6;
        add(clearBtn, gbc);

        gbc.gridx = 3;
        gbc.gridy = 6;
        add(outputBtn, gbc);

        // 添加选项卡面板
        gbc.gridx = 0;
        gbc.gridy = 7;
        gbc.gridwidth = 5;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        add(tabbedPane, gbc);

        // 添加进度条
        gbc.gridx = 0;
        gbc.gridy = 8;
        gbc.gridwidth = 5;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weighty = 0;
        add(progressBar, gbc);

        // 为按钮添加事件监听器（这里只是简单示例，可根据实际需求扩展）
        clearBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                insuredPlotField.setText("");
                themeCheckBox.setSelected(false);
                locateCheckBox.setSelected(false);
                reporeCheckBox.setSelected(false);
                wordCheckBox.setSelected(false);
                plantingRatioField.setText("");
                verificationRatioField.setText("");
                fullPlotCheckBox.setSelected(false);
                highestRatioCheckBox.setSelected(false);
                statTableField.setText("");
                outputPathField.setText("");
            }
        });

        outputBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 模拟输出过程
                simulateOutputProcess();
            }
        });

        insuredPlotBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 这里可以打开文件选择器或其他选择承保地块的逻辑
                //选则shp文件
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                // 限制只能选择.shp文件
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Shapefiles (.shp)", "shp");
                fileChooser.setFileFilter(filter);
                int returnValue = fileChooser.showOpenDialog(Main.this);
                if (returnValue == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    insuredPlotField.setText(selectedFile.getAbsolutePath());
                }
            }
        });

        statTableBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //弹出窗口选择excel文件
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                // 支持旧版与新版2中excel文件
//                FileNameExtensionFilter filter1 = new FileNameExtensionFilter("Excel Files (.xls)", "xls");
//                fileChooser.setFileFilter(filter1);
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel Files (.xlsx)", "xlsx");
                fileChooser.addChoosableFileFilter(filter);
                int returnValue = fileChooser.showOpenDialog(Main.this);
                if (returnValue == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    statTableField.setText(selectedFile.getAbsolutePath());
                }
            }
        });

        outputPathBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 这里可以打开文件选择器选择输出路径
                // 选择文件夹
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int returnValue = fileChooser.showOpenDialog(Main.this);
                if (returnValue == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    outputPathField.setText(selectedFile.getAbsolutePath());
                }
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main().setVisible(true);
            }
        });
    }

    private void initComponents() {
        insuredPlotLabel = new JLabel("承保地块:");
        insuredPlotField = new JTextField(20);
        insuredPlotBtn = new JButton("...");

        resultTypeLabel = new JLabel("成果类型:");
        themeCheckBox = new JCheckBox("专题图");
        locateCheckBox = new JCheckBox("坐落图");
        reporeCheckBox = new JCheckBox("报告");
        wordCheckBox = new JCheckBox("查验分户报告单");
        // 设置默认选中状态
        themeCheckBox.setSelected(true);
        locateCheckBox.setSelected(true);
        reporeCheckBox.setSelected(true);
        wordCheckBox.setSelected(true);

        plantingRatioLabel = new JLabel("种植占比:");
        plantingRatioField = new JTextField("75", 5);
        verificationRatioLabel = new JLabel("验标比例:");
        verificationRatioField = new JTextField("10", 5);

        plotFilterLogicLabel = new JLabel("地块筛选逻辑:");
        fullPlotCheckBox = new JCheckBox("全量地块出图");
        highestRatioCheckBox = new JCheckBox("最高占比出图");

        // 设置默认选中状态
        fullPlotCheckBox.setSelected(true);

        // 添加互斥逻辑
        fullPlotCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (fullPlotCheckBox.isSelected()) {
                    highestRatioCheckBox.setSelected(false);
                }
            }
        });

        highestRatioCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (highestRatioCheckBox.isSelected()) {
                    fullPlotCheckBox.setSelected(false);
                }
            }
        });

        statTableLabel = new JLabel("统计表格:");
        statTableField = new JTextField(20);
        statTableBtn = new JButton("...");


        reporeCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                statTableBtn.setVisible(reporeCheckBox.isSelected());
                statTableField.setVisible(reporeCheckBox.isSelected());
                statTableLabel.setVisible(reporeCheckBox.isSelected());
                plantingRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                plantingRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());

                plotFilterLogicLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                fullPlotCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                highestRatioCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
            }
        });
        locateCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                plantingRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                plantingRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());

                plotFilterLogicLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                fullPlotCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                highestRatioCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
            }
        });
        wordCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                plantingRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                plantingRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                verificationRatioField.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());

                plotFilterLogicLabel.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                fullPlotCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
                highestRatioCheckBox.setVisible(locateCheckBox.isSelected()||wordCheckBox.isSelected()||reporeCheckBox.isSelected());
            }
        });

        outputPathLabel = new JLabel("输出路径:");
        outputPathField = new JTextField(20);
        outputPathBtn = new JButton("...");

        clearBtn = new JButton("清除");
        outputBtn = new JButton("输出");

        tabbedPane = new JTabbedPane();


        logArea = new JTextPane();
        logArea.setEditable(false);
        //背景颜色
        logArea.setBackground(Color.LIGHT_GRAY);
        logArea.setFont(new Font("Arial", Font.PLAIN, 15));
        logScrollPane = new JScrollPane(logArea);
        logScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        doc=logArea.getStyledDocument();


        tabbedPane.addTab("日志", logScrollPane);

        // 初始化新增组件
        progressBar = new JProgressBar();
        progressBar.setStringPainted(true); // 显示进度文字
        progressBar.setVisible(true); // 默认隐藏


        // 设置自动滚动到底部
        DefaultCaret caret = (DefaultCaret) logArea.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);


    }

    // 模拟输出过程的方法
    private void simulateOutputProcess() {
        progressBar.setVisible(true);
        progressBar.setValue(0);
        clearText();
        //指定测试目录
//        insuredPlotField.setText("E:\\测试数据制图\\ct0.shp");
//        insuredPlotField.setText("E:\\测试数据制图\\刘玲玲\\ct5-全量地块出图\\ct5-全量地块出图\\ct0.shp");
//        statTableField.setText("E:\\测试数据制图\\统计表信息.xlsx");
//        outputPathField.setText("E:\\测试数据制图\\输出");
        logInfo("开始执行...");
        LogInterface log = Main.this;
        SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
            @Override
            protected Void doInBackground() throws Exception {
                //核对文件、目录是否存在
                if (!insuredPlotField.getText().isEmpty()) {
                    File insuredPlot = new File(insuredPlotField.getText());
                    if (!insuredPlot.exists()) {
                        logError("错误: 承保地块文件不存在");
                        return null;
                    }
                }else {
                    logError("错误: 承保地块文件不存在");
                    return null;
                }

                if (!outputPathField.getText().isEmpty()) {
                    File outputPath = new File(outputPathField.getText());
                    if (!outputPath.exists()) {
                        logWarn("错误: 输出路径不存在，创建文件夹");
                        outputPath.mkdirs();
                    }
                }else {
                    logError("错误: 输出路径不存在");
                    return null;
                }
                // 核对shp文件是否存在字段,字段是否必填
                if(!ShapeTool.checkShapeFile(insuredPlotField.getText(),log)){
                    logError("错误: 承保地块文件检查不通过，终止");
                    return null;
                }else {
                    logSuccess("承保地块文件检查通过");
                }
                if(reporeCheckBox.isSelected()){
                    if (!statTableField.getText().isEmpty()) {
                        File statTable = new File(statTableField.getText());
                        if (!statTable.exists()) {
                            logError("错误: 统计表格文件不存在");
                            return null;
                        }
                    }else {
                        logError("错误: 统计表格文件不存在");
                        return null;
                    }

                    // 核对excel文件是否存在字段,字段是否必填
                    if(!ExcelTool.hasRequiredFields(statTableField.getText())){
                        logError("错误: 统计表格文件检查不通过，终止");
                        return null;
                    }else {
                        logSuccess("统计表格文件检查通过");
                    }
                }

                progressBar.setValue(5);
                // 创建文件夹
                fileDirTool = new FileDirTool(insuredPlotField.getText(),outputPathField.getText(),log);
                if (!fileDirTool.createDir()) {
                    logError("错误: 创建文件夹失败，终止");
                }else {
                    logSuccess("创建文件夹成功");
                }
                progressBar.setValue(10);
                shapeEntity = new ShapeEntity(insuredPlotField.getText(),log);
                int taskCount=1;
                if(wordCheckBox.isSelected()){
                    taskCount++;
                }
                if(reporeCheckBox.isSelected()){
                    taskCount++;
                }
                if(themeCheckBox.isSelected()){
                    taskCount++;
                }
                int step=90/taskCount;
                int current=10;

                if(locateCheckBox.isSelected()){
                    logInfo("开始生成定位图");
                    logInfo(fullPlotCheckBox.isSelected()?"全量出图":"最高占比出图");
                    locationMapGen = new LocationMapGen(shapeEntity,
                            log,
                            new BigDecimal(plantingRatioField.getText()),
                            new BigDecimal(verificationRatioField.getText()),
                            fullPlotCheckBox.isSelected(),true);

                    fileDirTool.traverse(locationMapGen,current,current+ step);
                    logSuccess("生成定位图完成");
                }else if(wordCheckBox.isSelected()||reporeCheckBox.isSelected()){
                    //同样需要用到筛选逻辑
                        locationMapGen = new LocationMapGen(shapeEntity,
                                log,
                                new BigDecimal(plantingRatioField.getText()),
                                new BigDecimal(verificationRatioField.getText()),
                                fullPlotCheckBox.isSelected(),false);
                        fileDirTool.traverse(locationMapGen,current,current+ step);
                }
                current+= step;
                if(wordCheckBox.isSelected()){
                    logInfo("开始生成查验分户报告单");
                    try {
                        SurveyExcelGen surveyExcelGen = new SurveyExcelGen(log,locationMapGen.getTempLands(),locationMapGen.getInspectionReportList(),locationMapGen.isAll());

                        fileDirTool.traverse(surveyExcelGen,current,current+ step);
                        logSuccess("生成查验分户报告单完成");
                        current+= step;
                    }catch (Exception e){
                        logError("错误: 创建word文件失败，终止");
                        e.printStackTrace();
                        return null;
                    }

                }
                if(reporeCheckBox.isSelected()){
                    logInfo("开始生成遥感验标报告");
                    WordGen wordGen = new WordGen(log,
                            statTableField.getText(),
                            verificationRatioField.getText(),
                            locationMapGen.getTempLands(),
                            locationMapGen.getInspectionReportList(),
                            locationMapGen.getTotalVillageInfoMap()
                    );
                    fileDirTool.traverse(wordGen,current,current+ step);
                    logSuccess("生成遥感验标报告完成");
                    current+= step;
                }
                if(themeCheckBox.isSelected()){
                    logInfo("开始生成专题图");
                    MapGen mapGen = new MapGen(log,shapeEntity);
                    fileDirTool.traverse(mapGen,current,100);
                    logSuccess("生成专题图完成");
                }

                return null;
            }

            @Override
            protected void done() {
                // 任务完成后的处理
                progressBar.setValue(100);
                logSuccess("所有任务完成");
                //打开输出目录文件夹
                try {
                    Desktop.getDesktop().open(new File(outputPathField.getText()));
                }catch (IOException e){
                    logError("错误: 打开输出目录文件夹失败");
                }
            }

        };
        worker.execute();


        progressBar.setValue(100);
    }

    // 向输出区域添加带样式的文本
    private void appendText(String text, AttributeSet attr) {
        try {
            doc.insertString(doc.getLength(), text, attr);
            // 自动滚动到底部
            logArea.setCaretPosition(doc.getLength());
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }
    private void clearText() {
        //清空日志区域内文本
        try {
            doc.remove(0, doc.getLength());
            // 自动滚动顶部
            logArea.setCaretPosition(0);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void logError(String message) {
        SwingUtilities.invokeLater(() -> {
        appendText(message+"\n", ColoStyles.getRedAttr());
        });
    }

    @Override
    public void logWarn(String message) {
        SwingUtilities.invokeLater(() -> {
            appendText(message+"\n", ColoStyles.getYellowAttr());
        });
    }

    @Override
    public void logInfo(String message) {
        SwingUtilities.invokeLater(() -> {
            appendText(message+"\n", ColoStyles.getBlueAttr());
        });
    }

    @Override
    public void logDebug(String message) {
        SwingUtilities.invokeLater(() -> {
            appendText(message+"\n", ColoStyles.getGrayAttr());
        });
    }

    @Override
    public void logSuccess(String message) {
        SwingUtilities.invokeLater(() -> {
            appendText(message+"\n", ColoStyles.getGreenAttr());
        });
    }

    @Override
    public void updateProgress(int progress) {
        SwingUtilities.invokeLater(() -> {
            progressBar.setValue(progress);
        });
    }
}
